home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
asm
/
alib11b.zip
/
CODE1.ZIP
/
DEBUG
/
WATCH.ASM
< prev
Wrap
Assembly Source File
|
1994-10-03
|
11KB
|
422 lines
;
; WATCH is a resident program that watches for interrupts you specify
; and prints a quick note to the printer. The program contains a
; table (ctrl_tbl) which must be modified to specify which interrupts
; to watch. Programmed by Jeff Owens, kowens@teleport.com
;---------------------------------------------------------------------------
;
code segment
assume cs:code,ds:code
org 100h
entry: jmp initialize
;
; The following buffer is used to store interrupt information before it
; is sent to the printer.
;
ibuf_size equ 2*1800
ibuf label byte
db ibuf_size dup (0)
ibuf_end label byte
ibuf_ptr dw ibuf
;
; the following table is the key to program execution, entries control
; which interrupts are trapped and how processing occurs. The interrupt
; points at table "call" entry.
;
ctable struc
inum db ? ;interrupt number
db 0e8h ;call op code
process dw ? ;process address
db 0eah,0,0,0,0 ;far jump
rtn_off equ 5
rtn_seg equ 7
ctable ends
ctrl_tbl label byte
ctable<08h,,process1,,>
ctable<13h,,process1,,>
ctable<15h,,process1,,>
ctable<16h,,process1,,>
ctable<17h,,process1,,>
ctable<18h,,process1,,>
ctable<19h,,process1,,>
ctable<1ah,,process1,,>
ctable<1ch,,process1,,>
ctable<20h,,process1,,>
ctable<21h,,printint,,>
ctable<22h,,process1,,>
ctable<25h,,printint,,>
ctable<26h,,process1,,>
; ctable<28h,,process1,,> ;dos idle
ctable<2ah,,process1,,>
ctable<2bh,,process1,,>
ctable<2ch,,process1,,>
ctable<2dh,,process1,,>
ctable<2eh,,process1,,>
ctable<2fh,,printint,,>
ctable<31h,,process1,,>
ctable<32h,,process1,,>
ctable<33h,,process1,,>
ctable<34h,,process1,,>
ctable<35h,,process1,,>
ctable<36h,,process1,,>
ctable<37h,,process1,,>
ctable<38h,,process1,,>
ctable<39h,,process1,,>
ctable<40h,,process1,,>
ctable<54h,,process1,,>
db -1 ;end of table
;
; printer information
;
prn_buf db 'xxxx ' ;current print line
prn_buf_ptr dw 0 ;non zero if prn_buf has data
column_counter db 0 ;counts 16 columns accross
ax_save dw 0
bx_save dw 0
cx_save dw 0
dx_save dw 0
si_save dw 0
di_save dw 0
bp_save dw 0
ds_save dw 0
es_save dw 0
ax_save1 dw 0
bx_save1 dw 0
bp_save1 dw 0
es_save1 dw 0
lpt1_port dw 0
;----------------------------------------------------------------------------
; minimum process
; inputs: Stack points at return to calling table entry.
; No registers are saved.
;
process1:
cli
pushf
mov cs:ax_save1,ax
mov cs:bx_save1,bx
mov cs:bp_save1,bp
mov cs:es_save1,es
mov ax,0
mov es,ax
test byte ptr es:[417h],40h
jz process1_exit ;jmp if no caps lock
mov cs:prime_flag,1 ;set data collection state
mov bx,cs
mov es,bx
mov bp,sp
mov bx,ss:[bp+2] ;get return address
sub bx,4 ;point at start of table
mov ah,cs:[bx.inum] ;get this interrupt number
mov al,byte ptr cs:ax_save1+1 ;get origional -ah-
mov bx,cs:ibuf_ptr
mov word ptr cs:[bx],ax ;save data in buffer
add cs:ibuf_ptr,2
cmp bx,offset ibuf_end-2
jb process1_exit ;jmp if not at end yet
mov cs:ibuf_ptr,offset ibuf
process1_exit:
mov es,cs:es_save1
mov bp,cs:bp_save1
mov bx,cs:bx_save1
mov ax,cs:ax_save1
popf
sti
ret
;----------------------------------------------------------------------------
; print stored data
; inputs: Stack points at return to calling table entry.
; No registers are saved.
;
prime_flag db 0 ;0=uprimed
; 1=collecting data
; 2=print inprocess
local_ibuf_ptr dw 0
printint:
pushf
mov cs:ax_save,ax
mov cs:bx_save,bx
mov cs:cx_save,cx
mov cs:dx_save,dx
mov cs:bp_save,bp
mov cs:es_save,es
mov ax,0
mov es,ax
test byte ptr es:[417h],40h
jz start_printing
jmp printint_exit ;jmp if caps lock
start_printing:
cmp cs:prime_flag,0
je printint_exit ;jmp if no data saved yet
cmp cs:prime_flag,2
je check_for_ibuf_data ;jmp if print in process
mov ax,cs:ibuf_ptr
mov cs:local_ibuf_ptr,ax
mov cs:prime_flag,2
jmp do_crlf
check_for_ibuf_data:
;
; check if existing print data is avail.
;
cmp cs:prn_buf_ptr,0
je extract_ibuf_data ;jmp if no print data ready
print_entry:
mov bx,cs:prn_buf_ptr
mov al,byte ptr cs:[bx] ;get print data
call print_char ;try to print next char.
jc printint_exit ; jmp if printer busy
;
; one char. in prn_buf was printed, update pointer
;
inc bx
mov cs:prn_buf_ptr,bx ;update print pointer
cmp bx,offset prn_buf+5
jne print_entry ;jmp if more to print
;
; check if final column printed
;
mov al,cs:column_counter
inc al
mov cs:column_counter,al
cmp al,15 ;check if last column
je do_crlf
cmp al,16
jne keep_printing ;jmp if more data on line
mov cs:column_counter,0
jmp keep_printing ;jmp if starting a new line
do_crlf:
mov word ptr cs:prn_buf,0a0dh
mov word ptr cs:prn_buf+2,0
mov cs:prn_buf_ptr,offset prn_buf
jmp printint_exit
keep_printing:
mov cs:prn_buf_ptr,0 ;disable prt_buf
jmp printint_exit
;
; ibuf_ptr points at next store point, use as print starting point
;
extract_ibuf_data:
mov bx,cs:local_ibuf_ptr
add cs:local_ibuf_ptr,2 ;move pointer forward
cmp bx,offset ibuf_end -2
jb ck_for_data ;jmp if not at end of buffer
mov cs:local_ibuf_ptr,offset ibuf
ck_for_data:
cmp word ptr cs:[bx],0
je printint_exit ;jmp if nothing to print
;
; ibuf has data to be printed
;
mov cx,word ptr cs:[bx] ;get print data
mov word ptr cs:[bx],0 ; zap data entry printed
mov bx,offset prn_buf ;get data storage point
mov word ptr cs:prn_buf_ptr,bx ;store pointer to data
call word_to_hex_ascii
jmp print_entry
printint_exit:
mov es,cs:es_save
mov bp,cs:bp_save
mov dx,cs:dx_save
mov cx,cs:cx_save
mov bx,cs:bx_save
mov ax,cs:ax_save
popf
ret
;-------------------------------------------
; print char. in -al-
; output - carry set if printer busy and char. not printed.
; - register -dx- changed
;
print_char:
push ax
; mov dx,0
; mov ah,2
; int 17h ;get printer status
; test ah,80h
; jz busy_exit ;exit if printer busy
; pop ax
; mov ah,0
; int 17h
mov dx,cs:lpt1_port
inc dx ;select status port 379
in al,dx ;read printer status
test al,80h
jz busy_exit
pop ax
dec dx ;move to printer port
out dx,al ;print char.
mov dx,cs:lpt1_port
add dx,2 ;select data port 37a
mov al,0dh
out dx,al
out dx,al
mov al,0ch
out dx,al
out dx,al
clc
jmp pc_exit
busy_exit:
pop ax
stc
pc_exit:
ret
;-----------------------------------------------------------------------
; subroutine to convert byte to hex ascii
; inputs AL = hex
; cs:bx = storage point
;
byte_to_hex_ascii:
mov ah,al ;save data for later
and al,0fh ;isolate low nibble
add al,'0'
cmp al,'9'
jle next_nibble ;jump if conversion ok
add al,'A'-'9'-1
next_nibble:
xchg ah,al
shr al,1 ;right
shr al,1 ; justify
shr al,1 ; high
shr al,1 ; nibble
add al,'0'
cmp al,'9'
jle hex_store ;jump if conversion ok
add al,'A'-'9'-1
hex_store:
mov byte ptr cs:[bx],al
inc bx
mov byte ptr cs:[bx],ah
inc bx
ret
;---------------------------------------------------------------------------
; subroutine to convert word to hex ascii
; inputs cx = hex word
; cs:bx = store pointer
;
word_to_hex_ascii:
mov al,ch ;get high byte
call byte_to_hex_ascii ;convert and store one byte
mov al,cl ;get low byte
call byte_to_hex_ascii ;convert and store one byte
ret
;--------------------------------------------------------------------------
;------------------------------------------------------------------------------
; INITIALIZE grabs the needed vectors, then reserves enough memory for
; the program to remain resident.
;------------------------------------------------------------------------------
initialize:
;! int 3
mov ax,cs
mov ds,ax
mov es,ax
call check_printer
jz printer_ok
mov ah,9
mov dx,offset printer_msg
int 21h
mov ax,4c00h
int 21h
printer_ok:
;
; grab needed interrupt vectors. See table at start of program
;
mov si,offset ctrl_tbl ;point at first table entry
grab_int_loop:
cmp [si.inum],-1
je grab_int_done ;jmp if end of table
;
; fix table address for process to call
;
mov ax,[si.process]
sub ax,si ;compute delta
sub ax,4 ;adjust for table entry
mov [si.process],ax
;
; get current vector contents
;
mov al,[si.inum]
mov ah,35h
int 21h ;get vector in es:bx
mov word ptr ds:[si+rtn_off],bx
mov word ptr ds:[si+rtn_seg],es
;
; stuff our process address in vector
;
mov ax,cs
mov es,ax
mov dx,si
inc dx ;move to process point
mov al,[si.inum]
mov ah,25h
int 21h
add si,size ctable
jmp grab_int_loop
grab_int_done:
mov ax,cs
mov es,ax
mov ds,ax
mov dx,offset signon_msg
mov ah,9
int 21h
;
; save printer port adr
;
mov ax,0
mov es,ax
mov ax,word ptr es:[408h]
mov cs:lpt1_port,ax
;
; Exit by TSR int 31h.
;
mov dx,offset initialize
add dx,15
mov cl,4
shr dx,cl
mov ax,3100h
int 21h
;-----------------------------------------------------------------------------
printer_msg label byte
db 0dh,0ah
db ' This program requires the printer to be online and ready.',0dh,0ah
db ' Aborting without installing',0dh,0ah,'$'
signon_msg label byte
db 0dh,0ah
db ' Interrupt quick summary print.',0dh,0ah
db ' Caps lock on = collect data',0dh,0ah
db ' Caps lock off = print data',0dh,0ah,'$'
;-----------------------------------------------------------------------------
; check if printer ready
; inputs: none
; outputs: ah = 0 if printer ready (zero flag set)
;
check_printer:
mov dx,0 ;check printer #1 (lpt1)
mov ah,2 ;get printer status code
int 17h ;call bios
and ah,38h ;check if out of paper, online,error
xor ah,10h ;reverse online bit state
ret
;-----------------------------------------------------------------------│-
code ends
end entry